#ifndef _PGDATATABLE_H_
#define _PGDATATABLE_H_

#include <buildspec.h>
#include <Client/ClientUtils/Network/AbstractDataTable.h>
#include <Client/ClientUtils/Network/pg/PostgresDriver.h>
#include <string>
#include <boost/any.hpp>

#include <pqxx/pqxx>

namespace GST {
namespace ClientUtils {

	/**
	 * Return table of PostgresDriver. This class mainly wrappes a pqxx::result.
	 */
	class GST_API_EXPORT PGDataTable
		: public AbstractDataTable
	{
	public:
		
		///@name getter
		//@{
		virtual boost::any get(const std::type_info& returntype, int col);
		virtual bool isNull(int col);
		virtual std::string getName(int col) const;
		virtual TableAttributeDesc::DType getType(int col) const;
		virtual int getDimension(int col) const;
		virtual bool isNullable(int col) const;
		virtual bool nextRow();
		virtual unsigned int cols() const;
		//@}

		///@name old
		//@{
		virtual boost::any get(const std::type_info& returntype, int row, int col);
		virtual bool isNull(int row, int col);
		virtual unsigned int rows() const;
		//@}
		
	protected:
		virtual AbstractRDBAttributeDesc * newAttributeDesc(const TableAttributeDesc & desc, bool is_primaryKey=false) const;


	private:
		friend class PostgresDriver;

		//private c'tor
		PGDataTable(PostgresDriver::PQXXResultPtr r);

		///@name private members
		//@{
		PostgresDriver::PQXXResultPtr pqxxresult;
		int currentRow;
		//@}

		///@name private helpers
		//@{
		template<typename T> T getFieldAs(int row, int col);
		pqxx::field getField(int row, int col) const;
		void testPQXXResultPtr() const;
		//@}
	};//---------------- end of class ---------------------------------

	//typedefs:
	typedef boost::shared_ptr<PGDataTable> PGDataTablePtr;



	//------------------ template implementations ----------------------
	/** 
	 * get data
	 * @throws GST::exceptions::IsNull
	 */
	template<typename T>
	T
	PGDataTable::getFieldAs(int row, int col)
	{
		pqxx::field field = this->getField(row, col);
		if( field.is_null() )
		{
			throw GST::exceptions::IsNull(__METHOD_NAME__, this->getName(col), col);
		}
		else
		{
			return field.as<T>();
		}		
	}

} //of ns ClientUtils
} //of ns GST

#endif //_PGDATATABLE_H_